package m.system;

import m.common.action.Action;
import m.common.dao.Dao;
import m.common.model.HostInfo;
import m.common.service.HostInfoService;
import m.common.service.Service;
import m.system.exception.MException;
import m.system.util.ClassUtil;
import m.system.util.StringUtil;
import m.system.util.SystemUtil;
import manage.model.SystemInfo;
import manage.service.SystemInfoService;

import java.io.File;
import java.util.*;

public class RuntimeData {
	private static Map<String,Class<? extends Action>> actionData;
	public static Map<String, Class<? extends Action>> getActionData() {
		return actionData;
	}
	//set
	public static <T extends Action> void fillAction(String action_name,Class<T> action_class){
		if(null==actionData){
			actionData= new LinkedHashMap<>();
		}
		actionData.put(action_name, action_class);
	}
	//get
	public static Class<? extends Action> getAction(String action_name){
		if(null==actionData){
			return null;
		}
		return actionData.get(action_name);
	}
	private static Map<Class<? extends Service>,Service> serviceData;
	/**
	 * 获取service实例
	 *  <T>
	 *  clazz
	 * 
	 *  MException
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Service> T getService(Class<? extends T> clazz) throws MException{
		if(null==serviceData){
			serviceData= new HashMap<>();
		}
		T service=(T) serviceData.get(clazz);
		if(null==service){
			service=ClassUtil.newInstance(clazz);
			serviceData.put(clazz, service);
		}
		return service;
	}
	private static Map<Class<? extends Dao>,Dao> daoData;
	/**
	 * 获取dao实例
	 *  <T>
	 *  clazz
	 * 
	 *  MException
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Dao> T getDao(Class<? extends T> clazz) throws MException{
		if(null==daoData){
			daoData= new HashMap<>();
		}
		T dao=(T) daoData.get(clazz);
		if(null==dao){
			dao=ClassUtil.newInstance(clazz);
			daoData.put(clazz, dao);
		}
		return dao;
	}

	private static String classPath="";
	private static String classWeb="";
	private static String classTmp="";
	private static String publicPath="";
	private static String publicWeb="";
	private static String domainClass="";
	private static String tableSchema="";
	private static String serverIp="";
	private static int serverPort=8128;
	private static String serverAuth="";
	private static String serverName="";
	private static String filePath="";
	private static String modelPack="";
	private static String actionPack="";
	private static String handlerPack="";
	private static String secretField="";
	private static String staticField="";
	private static String taskClass="";
	private static String initClass="";
	private static String filterClass="";
	private static HostInfo hostInfo;//主机信息,
	private static Boolean debug=true;
	private static Boolean outLog=false;
	
	private static volatile Set<String> staticPropertyList=null;
	public static StringBuffer testStaticDomain(String property){
		if(null==staticPropertyList) {
			synchronized (RuntimeData.class) {
				if(null==staticPropertyList){
					staticPropertyList= new HashSet<>();
					String[] sp=staticField.split(",");
					staticPropertyList.addAll(Arrays.asList(sp));
				}
			}
		}
		if(staticPropertyList.contains(property)){
			return new StringBuffer(getStaticDomain());
		}else{
			return new StringBuffer();
		}
	}
	private static volatile Set<String> secretFieldList=null;
	public static boolean isSecretField(String property) {
		if(null==secretFieldList) {
			synchronized (RuntimeData.class) {
				if(null==secretFieldList) {
					secretFieldList= new HashSet<>();
					String[] sf=secretField.split(",");
					secretFieldList.addAll(Arrays.asList(sf));
				}
			}
		}
		return secretFieldList.contains(property);
	}
	private static long lastLong= 0L;
	private static String staticDomain="";
	private static String staticMode="";
	public static String getStaticDomain() {
		if(System.currentTimeMillis()-lastLong>5000) {
			try {
				lastLong=System.currentTimeMillis();
				SystemInfo model=getService(SystemInfoService.class).getUniqueModel();
				if(null!=model) {
					staticDomain=StringUtil.noSpace(model.getStaticDomain());
					staticMode=StringUtil.noSpace(model.getStaticMode());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if("A".equals(staticMode)) {
			return staticDomain;
		}else if("B".equals(staticMode)) {
			return HostInfoService.getRandomIP(null);
		}else if("C".equals(staticMode)) {
			return HostInfoService.getRandomIP(staticDomain);
		}else {
			return "";
		}
	}
	/**
	 * 是否允许随意访问文件路径
	 * 
	 */
	public static boolean accessFilePath() {
		return "A".equals(staticMode) || "C".equals(staticMode);
	}
	/**
	 * 清除临时文件目录
	 */
	public static void clearTmpFile() {
		deleteDir(classTmp);
	}
	private static void deleteDir(String path) {
		File file=new File(path);
		if(file.exists()) {
			File[] fs=file.listFiles();
			if(null!=fs) {
				for(File f : fs) deleteDir(f.getPath());
			}
			file.delete();
		}
	}
	
	public static String getClassPath() {
		return classPath;
	}
	public static String getClassWeb(){return classWeb;}
	public static String getClassTmp(){return classTmp;}
	public static void setClassPath(String classPath) {
		SystemUtil.printlnIf(true,"classPath:",classPath);
		RuntimeData.classPath = classPath;
		RuntimeData.classWeb=classPath+"web/";
		RuntimeData.classTmp=classPath+"tmp/";
	}
	public static String getPublicPath() {
		return publicPath;
	}
	public static String getPublicWeb(){return publicWeb;}
	public static void setPublicPath(String publicPath) {
		SystemUtil.printlnIf(true,"publicPath:",publicPath);
		RuntimeData.publicPath = publicPath;
		RuntimeData.publicWeb=publicPath+"web/";
	}
	public static String getFilePath() {
		return filePath;
	}
	public static void setFilePath(String filePath) {
		RuntimeData.filePath = filePath;
	}
	public static Boolean getDebug() {
		return debug;
	}
	public static void setDebug(Boolean debug) {
		RuntimeData.debug = debug;
	}
	public static String getDomainClass() {
		return domainClass;
	}
	public static void setDomainClass(String domainClass) {
		RuntimeData.domainClass = domainClass;
	}
	public static Boolean getOutLog() {
		return outLog;
	}
	public static void setOutLog(Boolean outLog) {
		RuntimeData.outLog = outLog;
	}
	public static String getServerIp() {
		return serverIp;
	}
	public static void setServerIp(String serverIp) {
		RuntimeData.serverIp = serverIp;
	}
	public static String getTableSchema() {
		return tableSchema;
	}
	public static void setTableSchema(String tableSchema) {
		RuntimeData.tableSchema = tableSchema;
	}
	public static int getServerPort() {
		return serverPort;
	}
	public static void setServerPort(int serverPort) {
		RuntimeData.serverPort = serverPort;
	}
	public static String getServerAuth() {
		return serverAuth;
	}
	public static void setServerAuth(String serverAuth) {
		RuntimeData.serverAuth = serverAuth;
	}

	public static String getServerName() {
		return serverName;
	}

	public static void setServerName(String serverName) {
		RuntimeData.serverName = serverName;
	}

	public static HostInfo getHostInfo() {
		return hostInfo;
	}
	public static void setHostInfo(HostInfo hostInfo) {
		RuntimeData.hostInfo = hostInfo;
	}

	public static String getFilterClass() {
		return filterClass;
	}

	public static void setFilterClass(String filterClass) {
		RuntimeData.filterClass = filterClass;
	}

	public static String getSecretField() {
		return secretField;
	}
	public static void setSecretField(String secretField) {
		RuntimeData.secretField = secretField;
	}
	public static void addSecretField(String... secretField) {
		for(String field : secretField) {
			RuntimeData.secretField+=","+field;
		}
	}
	public static String getStaticField() {
		return staticField;
	}
	public static void setStaticField(String staticField) {
		RuntimeData.staticField = staticField;
	}
	public static void addStaticField(String... staticField) {
		for(String field : staticField) {
			RuntimeData.staticField+=","+field;
		}
	}
	public static String getModelPack() {
		return modelPack;
	}
	public static void setModelPack(String modelPack) {
		RuntimeData.modelPack = modelPack;
	}
	public static void addModelPack(String... modelPack) {
		for(String pack : modelPack) {
			RuntimeData.modelPack+=","+pack;
		}
	}
	public static String getActionPack() {
		return actionPack;
	}
	public static void setActionPack(String actionPack) {
		RuntimeData.actionPack = actionPack;
	}
	public static void addActionPack(String... actionPack) {
		for(String pack : actionPack) {
			RuntimeData.actionPack+=","+pack;
		}
	}
	public static String getHandlerPack() {
		return handlerPack;
	}
	public static void setHandlerPack(String handlerPack) {
		RuntimeData.handlerPack = handlerPack;
	}
	public static void addHandlerPack(String... handlerPack) {
		for(String pack : handlerPack) {
			RuntimeData.handlerPack+=","+pack;
		}
	}
	public static String getTaskClass() {
		return taskClass;
	}
	public static void setTaskClass(String taskClass) {
		RuntimeData.taskClass = taskClass;
	}
	public static void addTaskClass(String... taskClass) {
		for(String pack : taskClass) {
			RuntimeData.taskClass+="&"+pack;
		}
	}
	public static String getInitClass() {
		return initClass;
	}
	public static void setInitClass(String initClass) {
		RuntimeData.initClass = initClass;
	}
	public static void addInitClass(String... initClass) {
		for(String pack : initClass) {
			RuntimeData.initClass+=","+pack;
		}
	}
	
}
